package com.xqboss.web.controller.box;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xqboss.apps.domain.box.Box;
import com.xqboss.apps.domain.box.BoxNft;
import com.xqboss.apps.domain.box.BoxSimulatedRecord;
import com.xqboss.apps.domain.nft.Category;
import com.xqboss.apps.domain.nft.Nft;
import com.xqboss.apps.dto.box.BindBoxDto;
import com.xqboss.apps.dto.box.BoxDto;
import com.xqboss.apps.dto.box.BoxSaleableDto;
import com.xqboss.apps.dto.box.BoxSimulatedRecordDto;
import com.xqboss.apps.service.box.BoxNftService;
import com.xqboss.apps.service.box.BoxService;
import com.xqboss.apps.service.box.BoxSimulatedRecordService;
import com.xqboss.apps.service.nft.CategoryService;
import com.xqboss.apps.service.nft.NftService;
import com.xqboss.apps.vo.box.BoxInfoVoTwo;
import com.xqboss.apps.vo.box.BoxVo;
import com.xqboss.apps.vo.nft.BoxSimulatedRecordVo;
import com.xqboss.common.annotation.Log;
import com.xqboss.common.annotation.RepeatSubmit;
import com.xqboss.common.core.controller.BaseController;
import com.xqboss.common.core.domain.R;
import com.xqboss.common.enums.BusinessType;
import com.xqboss.common.exception.ServiceException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author Administrator
 */
@Api(tags = {"箱子管理"})
@RestController
@RequestMapping("/web/box")
public class WebBoxController extends BaseController {
    @Autowired
    private BoxService boxService;
    @Autowired
    private BoxSimulatedRecordService boxSimulatedRecordService;
    @Autowired
    private BoxNftService boxNftService;
    @Autowired
    private NftService nftService;
    @Resource
    private CategoryService categoryService;

    @PreAuthorize("@ss.hasPermi('web:box:list-page')")
    @ApiOperation("箱子管理列表")
    @PostMapping("list-page")
    public R<List<BoxVo>> boxList(@RequestBody BoxDto dto) {
        dto.startPage();
        List<BoxVo> vo = boxService.selectListByDto(dto);
        return R.ok(vo);
    }

    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:box:add')")
    @ApiOperation("添加箱子")
    @Log(title = "添加箱子", businessType = BusinessType.INSERT)
    @PostMapping("add")
    public R add(@Validated @RequestBody BoxDto dto) {
        boxService.insert(dto);
        return R.ok();
    }

    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:box:edit')")
    @ApiOperation("编辑箱子")
    @Log(title = "编辑箱子", businessType = BusinessType.UPDATE)
    @PutMapping("edit")
    public R edit(@Validated @RequestBody BoxDto dto) {
        boxService.update(dto);
        return R.ok();
    }

    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:box:untie')")
    @ApiOperation("解绑箱子")
    @Log(title = "解绑箱子", businessType = BusinessType.UPDATE)
    @PutMapping("untie/{boxId}")
    public R untie(@PathVariable("boxId")
                   @ApiParam(value = "箱子id", required = true)
                   @NotNull(message = "请输入箱子id")
                   Long boxId) {
        boxService.untie(boxId, getUserId());
        return R.ok();
    }

    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:box:update-saleable')")
    @ApiOperation("宝盒上下架")
    @PutMapping("update-saleable")
    @Log(title = "宝盒", businessType = BusinessType.UPDATE)
    public R updateSaleable(@Validated @RequestBody BoxSaleableDto dto) {
        boxService.changeSaleable(dto);
        return R.ok();
    }

    @PreAuthorize("@ss.hasPermi('web:box:info')")
    @ApiOperation("箱子详情")
    @GetMapping(value = "info/{id}")
    public R<BoxInfoVoTwo> getInfo(@PathVariable("id")
                                @ApiParam(value = "箱子id", required = true)
                                @NotNull(message = "请输入箱子id")
                                Long id) {
        Box box = boxService.getById(id);
        if (Objects.isNull(box)) {
            return R.fail("箱子不存在");
        }
        BoxInfoVoTwo vo = BeanUtil.copyProperties(box, BoxInfoVoTwo.class);
//        vo.setRemainderStock(box.getStock() - box.getSales());
        Category category = categoryService.getById(vo.getCategoryId());
        if (ObjUtil.isNotNull(category)) {
            vo.setParentId(Long.valueOf(category.getParentId()));
        }
        //箱子详情绑定的典藏nft信息
        List<BoxNft> boxNft = boxNftService.list(new LambdaQueryWrapper<BoxNft>().eq(BoxNft::getBoxId, box.getId()));
        if (CollUtil.isNotEmpty(boxNft)) {
            List<BindBoxDto> dtos = new ArrayList<>();
            boxNft.forEach(item -> {
                BindBoxDto bindBoxDto = new BindBoxDto();
                Nft nft = nftService.getById(item.getNftId());
                if (Objects.isNull(nft)) {
                    throw new ServiceException("藏品：" + item.getNftId() + "不存在！");
                }
                bindBoxDto.setNftId(nft.getId());
                bindBoxDto.setTitle(nft.getTitle());
                bindBoxDto.setStock(nft.getStock());
                bindBoxDto.setBindCount(item.getStock());
                dtos.add(bindBoxDto);
            });
            vo.setBindNft(dtos);
        }
        return R.ok(vo);
    }

    @PreAuthorize("@ss.hasPermi('web:box:simulated-list')")
    @ApiOperation("虚拟销量增发记录列表")
    @PostMapping("simulated-list")
    public R<BoxSimulatedRecordVo> publishList(@RequestBody BoxSimulatedRecordDto dto) {
        LambdaQueryWrapper<BoxSimulatedRecord> wq = new LambdaQueryWrapper<>();
//        wq.eq(BoxSimulatedRecord::getUserId, getUserId());
        wq.eq(BoxSimulatedRecord::getBoxId, dto.getBoxId());
        wq.orderByDesc(BoxSimulatedRecord::getCreateTime);
        List<BoxSimulatedRecord> list = boxSimulatedRecordService.list(wq);
        BoxSimulatedRecordVo vo = new BoxSimulatedRecordVo();
        if (CollUtil.isNotEmpty(list)) {
            vo.setRecords(list);
            vo.setAddCount(list.stream().map(BoxSimulatedRecord::getAmount).collect(Collectors.toList()).stream().mapToInt(Integer::intValue).sum());
        }
        return R.ok(vo);
    }

    @RepeatSubmit(interval = 1000, justUrl = true)
    @PreAuthorize("@ss.hasPermi('web:box:simulated-add')")
    @ApiOperation("添加虚拟销量")
    @GetMapping("simulated-add/{boxId}/{simulatedSales}")
    public R simulatedAdd(@PathVariable("boxId")
                          @ApiParam(value = "箱子id", required = true)
                          @NotNull(message = "请输入箱子id")
                          Long boxId,
                          @PathVariable("simulatedSales")
                          @ApiParam(value = "虚拟销量", required = true)
                          @NotNull(message = "请输入虚拟销量")
                          Integer simulatedSales) {
        return boxSimulatedRecordService.simulatedAdd(boxId, simulatedSales);
    }
}
